package com.github.baichuan.application.scaffold.jpa.authorization;

import com.github.baichuan.application.scaffold.domain.application.Application;
import com.github.baichuan.application.scaffold.domain.authorization.Resource;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import java.util.List;
import java.util.Optional;

public interface ResourceRepository extends JpaRepository<Resource, String> {

    @Query("select resource from Resource resource where id=:id and application=:application")
    Optional<Resource> findById(@Param("application") Application application, @Param("id") String id);

    @Query("select resource from Resource resource where application=:application and code=:code")
    Optional<Resource> findByCode(@Param("application") Application application, @Param("code") String code);

    @Query("select resource from Resource resource where resource.parent=:resource")
    List<Resource> getChildren(@Param("resource") Resource resource);

//    @Query("select resource from Resource resource where application=:application and id in (:ids)")
//    List<Resource> findAll(@Param("application") Application application, @Param("ids") List<String> ids);

    List<Resource> findByApplication(Application application);

    @Query(value = "SELECT r.* FROM resource r\n" +
            "WHERE kind='menu' and EXISTS(\n" +
            "    SELECT * FROM role_privilege rp JOIN role role ON rp.role_id=role.id\n" +
            "    JOIN application_member_privilege amp ON amp.role_id=role.id\n" +
            "    JOIN application_member am ON am.id=amp.application_member_id\n" +
            "    JOIN application app ON app.id=am.application_id\n" +
            "    WHERE rp.resource_id=r.id AND app.code=:application AND am.id=:id\n" +
            ")", nativeQuery = true)
    List<Resource> getAuthorizedMenus(@Param("application") String application, @Param("id") String applicationMemberId);

    @Query(value = "SELECT r.* FROM resource r\n" +
            "WHERE EXISTS(\n" +
            "    SELECT * FROM role_privilege rp JOIN role role ON rp.role_id=role.id\n" +
            "    JOIN application_member_privilege amp ON amp.role_id=role.id\n" +
            "    JOIN application_member am ON am.id=amp.application_member_id\n" +
            "    JOIN application app ON app.id=am.application_id\n" +
            "    WHERE rp.resource_id=r.id AND app.code=:application AND am.id=:id\n" +
            ")", nativeQuery = true)
    List<Resource> getAuthorized(@Param("application") String application, @Param("id") String applicationMemberId);

    @Modifying
    @Query(value = "delete from role_privilege where resource_id=:resourceId", nativeQuery = true)
    void removeRolePrivilege(@Param("resourceId") String resourceId);

//    @Query(value = "SELECT r.* FROM resource r JOIN role_privilege rp ON r.id=rp.resource_id\n" +
//            "    JOIN role ON rp.role_id=role.id\n" +
//            "    JOIN application_member_privilege amp ON amp.role_id=role.id\n" +
//            "    JOIN application_member am ON am.id=amp.application_member_id\n" +
//            "WHERE am.uid=:uid AND r.code=:code", nativeQuery = true)
//    Optional<Resource> findAuthorized(@Param("uid") String uid, @Param("code") String code);

//    @Query(value = "select resource from Resource resource where resource.application.code=:application " +
//            "and resource.code <> '' and resource.code is not null "
//    )
//    List<Resource> getPermissionFilterList(@Param("application") String application);
}

